#ifndef SCENEMANAGER_H
#define SCENEMANAGER_H

#include "ISceneManager.h"
#include "QuadTreeNode.h"
#include "QuadTreeLeaf.h"


class CDataSceneManager;

//!Scene manager class which handle the quad tree used for collision.
class CSceneManager: public ISceneManager
{
private:
	//!Quadtree root.
	CQuadTreeNode m_rootQuadTree;

	//!Depth of the quatree
	int m_depth;

	//!Total width of the scene.
	int m_width;

	//!Total height of the scene.
	int m_height;

	//!Array storing pointers to the leaf nodes.
	vector<CQuadTreeLeaf*> m_arrayOfLeaves;

public:
	//!Constructor
	CSceneManager(void);

	//!Destructor
	~CSceneManager(void);

	//!Initialisation of the scene manager.
	/*!
	It creates an empty tree.
	\param depth Depth of the tree.
	*/
	bool init(int depth);
	
	//!Get a vector of entity. 
	/*!
	All the entities are in the same quad as entity. As an entity can be in several quad, indexLeaf says which quad we 
	want. If there is no vector of entity of the given index, it returns 0.
	\param entity A pointer to the entity that we want the quad from
	\param indexLeaf The index of the quad that we want.
	\return Return a pointer to a vector of entities. If indexLeaf doesn't exist, it returns 0.
	*/
	vector<IShape*>* getVector(IShape* entity, int indexLeaf);

	//!Update the position of an entity in the quad tree.
	/*!
	When an entity moves, it needs to be moved also in the quad tree.
	\param entity The entity to update.
	*/
	void updateEntity(IShape* entity);

	//!Scroll the boundaries of the quad tree.
	/*!
	When the world is scrolled, the boundaries of the quad tree become false. Scrolling them with the same vectors make
	them good again.
	\param v Vector representing the translation of the boundaries.
	*/
	void scrollBoundaries(const CVector2i& v);

	//!Add an entity in the quad tree.
	/*!
	\param entity A pointer to the entity to add in the quad tree.
	*/
	void addEntity(IShape* entity);

	//!Add an entity in the quad tree.
	/*!
	\param physicEntity A pointer to the entity to add in the quad tree.
	*/

private:

	//!Create the tree.
	/*!
	It creates empty nodes and leaf. This function is called recursively with depth = depth-1.
	\param node The root of the quad tree.
	\param depth The depth of the quad tree.
	\return True if the tree is created. False if it failed.
	*/
	bool createTree(CQuadTreeNode* node, int depth);

	//!Set the boundaries of every nodes in the tree.
	/*!
	This function is called recursively.
	\param node The root of the quad tree.
	\param minX The minumum boundary of the root in the X axis.
	\param minY The minimum boundary of the root in the Y axis.
	\param maxX The maximum boundary of the root in the X axis.
	\param maxY The maximum boundary of the root in the Y axis
	\param depth The depth of the quad tree.
	*/
	void setBoundaries(CQuadTreeNode* node, int minX, int minY, int maxX, int maxY, int depth);

	//!Return the leaf node representing the area where the vector v is.
	/*!
	This function is called recursively.
	\param v Vector represetning the position that we are looking for in the tree.
	\param node Root of the quad tree.
	\depth Depth of the quad tree.
	\return ~Return a pointer to the leaf representing the area where the vector v is.
	*/
	CQuadTreeLeaf* getLeafNode(const CVector2i& v, CQuadTreeNode* node, int depth);

	//!Delete an entity from the tree.
	/*!
	\param entity A pointer to the entity to delete in the tree.
	*/
	void deleteEntity(IShape* entity);

	//!Add an entity in the quad tree.
	/*!
	\param entity The entity to add in the quad tree.
	*/
	void putEntity(IShape* entity);

	//!Scroll the boundaries of the tree.
	/*!
	\param v The translation vector for the boundaries.
	\param node The root of the quad tree.
	\param depth The depth of the tree.
	*/
	void scroll(const CVector2i& v, CQuadTreeNode* node, int depth);

	//!Delete the entire tree.
	/*!
	\param node The root of the tree.
	\param depth The depth of the tree.
	*/
	void deleteTree(CQuadTreeNode* node, int depth);

	//!Get all the vector of entities from the areas represented by minX, maxX, minY maxY
	/*!
	\param minX The minimum boundary in the x axis for the area that we are looking for.
	\param maxX The maximum boundary in the x axis for the area that we are looking for.
	\param minY The minimum boundary in the y axis for the area that we are looking for.
	\param maxY The maximum boundary in the y axis for the area that we are looking for.
	\param node The root of the quad tree.
	\param pntVector Reference to a vector of vector of entities. The function fills it.
	*/
	void getVector(int minX, int maxX, int minY, int maxY, CQuadTreeNode* node, vector<vector<IShape*>*>& pntVector);
};

#endif
